﻿package com.coo.automaton 
{
	import com.coo.events.HangulAutomatonEvent;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import gs.TweenLite;
	
	/**
	 * ...
	 * @author iCoo
	 */
	public class KeyboardPad extends MovieClip
	{
		public static var KOR: String = "kor";
		public static var ENG: String = "eng";
		public static var LANGUAGE: String;
		
		private var _tf: TextField;
		private var _auto: HangulAutomaton;
		
		private var _sbi: int;
		private var _sei: int;
		private var _isShift: Boolean = false;
		
		private var _selectedBn: MovieClip;
		
		public function KeyboardPad()
		{
			addEventListener( Event.ADDED_TO_STAGE, init );
		}
		
		private function init( e: Event ): void
		{
			removeEventListener( Event.ADDED_TO_STAGE, init );
			
			_auto = new HangulAutomaton();
			
			addEvent();
		}
		
		public function typing( tf: TextField, lang: String = "eng" ): void
		{
			_tf = tf;
			
			_auto.reset();
			
			_sbi = _tf.selectionBeginIndex;
			_sei = _tf.selectionEndIndex + 1;
			
			KeyboardPad.LANGUAGE = lang;
			stage.focus = _tf;
			
			trace( "SBI  : " + _sbi + "  -  " + "SEI : " +  _sei );
			trace( "SBI2  : " + _tf.selectionBeginIndex + "  -  " + "SEI2 : " +  _tf.selectionBeginIndex );
		}
		
		private function addEvent(): void
		{
			for (var i:int = 0; i < this.numChildren; i++) 
			{
				var mc: MovieClip = this.getChildAt( i ) as MovieClip;
				
				mc.bn.addEventListener( MouseEvent.MOUSE_DOWN, pressHandler );
				mc.bn.addEventListener( MouseEvent.CLICK, clickHandler );
			}
			
			_auto.addEventListener( HangulAutomatonEvent.ALPHABET_ADDED, syllabicHandler );
			_auto.addEventListener( HangulAutomatonEvent.NO_ALPHABET_ADDED, syllabicHandler);
			_auto.addEventListener( HangulAutomatonEvent.SYLLABIC_COMPOSED, syllabicHandler);
		}
		
		//_____________________________ Handlers ________________________________
		
		private function syllabicHandler( e: HangulAutomatonEvent ): void
		{
			switch( e.type )
			{
				case HangulAutomatonEvent.ALPHABET_ADDED:
					trace( "syllabic add : " + e.syllabic );
					_tf.replaceText( _sbi, _sei, e.syllabic );
				break;
				
				case HangulAutomatonEvent.SYLLABIC_COMPOSED:
					trace( "syllabic complete : " + e.syllabic );
					_tf.replaceText( _sbi, _sei, e.syllabic );
					nextSyllabic();
				break;
			}
		}
		
		private function clickHandler( e: MouseEvent ): void
		{
			switch( e.target.parent.name )
			{
				case "bn_0":
					_auto.addAlphabet( "0" );
				break;
				
				case "bn_1":
					_auto.addAlphabet( "1" );
				break;
				
				case "bn_2":
					_auto.addAlphabet( "2" );
				break;
				
				case "bn_3":
					_auto.addAlphabet( "3" );
				break;
				
				case "bn_4":
					_auto.addAlphabet( "4" );
				break;
				
				case "bn_5":
					_auto.addAlphabet( "5" );
				break;
				
				case "bn_6":
					_auto.addAlphabet( "6" );
				break;
				
				case "bn_7":
					_auto.addAlphabet( "7" );
				break;
				
				case "bn_8":
					_auto.addAlphabet( "8" );
				break;
				
				case "bn_9":
					_auto.addAlphabet( "9" );
				break;
				
				case "bn_A":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "a" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "A" ) : _tf.appendText( "a" );
					}
				break;
				
				case "bn_B":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "b" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "B" ) : _tf.appendText( "b" );
					}
				break;
				
				case "bn_C":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "c" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "C" ) : _tf.appendText( "c" );
					}
				break;
				
				case "bn_D":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "d" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "D" ) : _tf.appendText( "d" );
					}
				break;
				
				case "bn_E":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "E" ) : _auto.addAlphabet( "e" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "E" ) : _tf.appendText( "e" );
					}
				break;
				
				case "bn_F":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "f" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "F" ) : _tf.appendText( "f" );
					}
				break;
				
				case "bn_G":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "g" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "G" ) : _tf.appendText( "g" );
					}
				break;
				
				case "bn_H":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "h" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "H" ) : _tf.appendText( "h" );
					}
				break;
				
				case "bn_I":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "i" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "I" ) : _tf.appendText( "i" );
					}
				break;
				
				case "bn_J":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "j" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "J" ) : _tf.appendText( "j" );
					}
				break;
				
				case "bn_K":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "k" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "K" ) : _tf.appendText( "k" );
					}
				break;
				
				case "bn_L":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "l" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "I" ) : _tf.appendText( "l" );
					}
				break;
				
				case "bn_M":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "m" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "M" ) : _tf.appendText( "m" );
					}
				break;
				
				case "bn_N":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "n" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "N" ) : _tf.appendText( "n" );
					}
				break;
				
				case "bn_O":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "O" ) : _auto.addAlphabet( "o" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "O" ) : _tf.appendText( "o" );
					}
				break;
				
				case "bn_P":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "P" ) : _auto.addAlphabet( "p" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "P" ) : _tf.appendText( "p" );
					}
				break;
				
				case "bn_Q":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "Q" ) : _auto.addAlphabet( "q" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "Q" ) : _tf.appendText( "q" );
					}
				break;
				
				case "bn_R":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "R" ) : _auto.addAlphabet( "r" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "R" ) : _tf.appendText( "r" );
					}
				break;
				
				case "bn_S":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "s" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "S" ) : _tf.appendText( "s" );
					}
				break;
				
				case "bn_T":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "T" ) : _auto.addAlphabet( "t" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "T" ) : _tf.appendText( "t" );
					}
				break;
				
				case "bn_U":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "u" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "U" ) : _tf.appendText( "u" );
					}
				break;
				
				case "bn_V":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "v" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "V" ) : _tf.appendText( "v" );
					}
				break;
				
				case "bn_W":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						( _isShift )? _auto.addAlphabet( "W" ) : _auto.addAlphabet( "w" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "W" ) : _tf.appendText( "w" );
					}
				break;
				
				case "bn_X":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "x" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "X" ) : _tf.appendText( "x" );
					}
				break;
				
				case "bn_Y":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "y" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "Y" ) : _tf.appendText( "y" );
					}
				break;
				
				case "bn_Z":
					if ( KeyboardPad.LANGUAGE == KeyboardPad.KOR )
					{
						_auto.addAlphabet( "z" );
					} else
					{
						nextSyllabic();
						( _isShift )? _tf.appendText( "Z" ) : _tf.appendText( "z" );
					}
				break;
				
				// SHIFT Key
				case "bn_ST":
				break;
				
				case "bn_DOT":
					nextSyllabic();
					_tf.appendText( "." );
				break;
				
				case "bn_BAR":
					nextSyllabic();
					_tf.appendText( "_" );
				break;
				
				case "bn_SP":
					_auto.releaseSyllabic();
					_tf.appendText(" ");
					nextSyllabic();
				break;
				
				case "bn_BSP":
					if ( KeyboardPad.LANGUAGE == "kor" )
					{
						var isType: Boolean = typeCheck( _tf.text.substr(-1));
						var temp: String = _auto.backspace();
						
						if ( temp == "" )
						{
							_tf.text = _tf.text.substring( 0, _tf.text.length - 1 );
							if( !isType ) prevSyllabic();
							_tf.setSelection( _sbi, _sbi );
						} else
						{
							_tf.replaceText( _sbi, _sei, temp );
						}
					} else
					{
						_tf.text = _tf.text.substring( 0, _tf.text.length - 1 );
						prevSyllabic();
						_tf.setSelection( _sbi, _sbi );
					}
				break;
				
				default :
				break;
			}
			
			stage.focus = _tf;
			trace( "SBI  : " + _sbi + "  -  " + "SEI : " +  _sei );
			trace( "SBI2  : " + _tf.selectionBeginIndex + "  -  " + "SEI2 : " +  _tf.selectionBeginIndex );
		}
		
		private function pressHandler( e: MouseEvent ): void
		{
			if ( e.target.parent.name != "bn_ST" )
			{
				_selectedBn = e.target.parent as MovieClip;
				
				TweenLite.to( _selectedBn.bg, 0.2, { alpha: 0.7 } );
				stage.addEventListener( MouseEvent.MOUSE_UP, releaseHandler );
			} else
			{
				_isShift = true;
				TweenLite.to( bn_ST.bg, 0.2, { alpha: 0.7 } );
			}
		}
		
		private function releaseHandler( e: MouseEvent ): void
		{
			stage.removeEventListener( MouseEvent.MOUSE_UP, releaseHandler );
			
			TweenLite.to( _selectedBn.bg, 0.2, { alpha: 1, onComplete: function(): void
			{
				if ( _isShift )
				{
					_isShift = false;
					TweenLite.to( bn_ST.bg, 0.2, { alpha: 1 } );
				}
			}} );
		}
		
		//_____________________________ Mothods ________________________________
		
		private function typeCheck( value: String ): Boolean
		{
			switch( value )
			{
				case "0" :
				case "1" :
				case "2" :
				case "3" :
				case "4" :
				case "5" :
				case "6" :
				case "7" :
				case "8" :
				case "9" :
				case "." :
				case "_" :
					return false;
				break;
				
				default :
					return true;
				break;
			}
		}
		
		private function nextSyllabic(): void
		{
			_sbi++;
			_sei++;
		}
		
		private function prevSyllabic(): void
		{
			_sbi--;
			_sei--;
		}
	}
}